package org.nViron;

import com.sun.opengl.util.Animator;
import java.awt.Frame;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLEventListener;
import org.nViron.nvParams.nvContextParamMgr.CONTEXTPARAM;
import org.nViron.nvParams.nvParamBindingMgr;
import org.nViron.nvProjection.nvMercator;
import org.nViron.nvCommon.nvPosition;
import org.nViron.nvConfig.nvConfig;
import org.nViron.nvParams.nvParamBinding;
import org.nViron.nvParams.nvVizParamMgr.VIZPARAM;
import org.nViron.nvRender.nvRenderer;
import org.nViron.nvSim.nvSimulator;

/**
 * Test project with minimal dependencies and functionality just for testing and developing the organic information design
 * @author Roland Haring <p>
 * <script type="text/javascript" src="http://www.ohloh.net/p/376434/widgets/project_basic_stats.js"></script>
 */
public class VizTest implements GLEventListener {

    private nvSimulator simulator;
    private nvConfig config;

    private nvPosition defaultPos = new nvPosition(14.32, 48.336, 0.0f);
    private static final VizTest that = new VizTest();
        
    private ArrayList dataEntityIds = new ArrayList();

    private long updatestamp = System.currentTimeMillis();

    private void keyPressed(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_A: {
                int id = simulator.getDataEntityMgr().addDataEntity(new SimpleDataEntity(simulator.getDataEntityMgr(), new nvPosition(defaultPos)));
                dataEntityIds.add(new Integer(id));
                break;
            }
            case KeyEvent.VK_R: {
                if (dataEntityIds.size() > 0) {
                    Integer id = (Integer) dataEntityIds.get(0);
                    simulator.getDataEntityMgr().removeDataEntity(id.intValue());
                    dataEntityIds.remove(0);
                }
                break;
            }
            case KeyEvent.VK_UP:
                simulator.movCamera(25.0f);
                break;
            case KeyEvent.VK_DOWN:
                simulator.movCamera(-25.0f);
                break;
            case KeyEvent.VK_LEFT:
                simulator.rotCamera(-10.0f);
                break;
            case KeyEvent.VK_RIGHT:
                simulator.rotCamera(10.0f);
                break;
        }
    }

    public static void main(String[] args) {
        Frame frame = new Frame("nViron VizTest");
        GLCanvas canvas = new GLCanvas();

        canvas.addGLEventListener(that);
        frame.add(canvas);
        frame.setSize(640, 480);
        final Animator animator = new Animator(canvas);
        frame.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                // Run this on another thread than the AWT event queue to
                // make sure the call to Animator.stop() completes before
                // exiting
                new Thread(new Runnable() {

                    public void run() {
                        animator.stop();
                        System.exit(0);
                    }
                }).start();
            }
        });

        frame.addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent e) {
                that.keyPressed(e);
                super.keyPressed(e);
            }
        });

        // Center frame
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        animator.start();
    }

    public void init(GLAutoDrawable _drawable) {
        // Use debug pipeline
        // drawable.setGL(new DebugGL(drawable.getGL()));

        config = new nvConfig() {
            @Override
            public void saveConfig(String ressource) {
            }

            @Override
            public void loadConfig(String ressource) {
            }

            public void saveParams(nvParamBindingMgr bindingMgr) {
                throw new UnsupportedOperationException("Not supported yet.");
            }

            public void loadParams(nvParamBindingMgr bindingMgr) {
                throw new UnsupportedOperationException("Not supported yet.");
            }

            public void setParamConfigFileName(String filename) {
                throw new UnsupportedOperationException("Not supported yet.");
            }

            public String getParamConfigFileName() {
                throw new UnsupportedOperationException("Not supported yet.");
            }
        };

        simulator = nvSimulator.getInstance();
        simulator.init(config, new nvMercator());
        nvRenderer renderer = new SimpleRenderer(simulator, _drawable);
        renderer.init();
        simulator.setRenderer(renderer);

        initScene();
    }

    private void initScene() {

        for (int i = 0; i < 0; i++) {
            SimpleDataEntity entity = new SimpleDataEntity(simulator.getDataEntityMgr(), new nvPosition(defaultPos));
            simulator.addDataEntity(entity);
        }

        nvParamBinding binding = new nvParamBinding(VIZPARAM.BIODIVERSITY_L1);
        binding.addTerm(CONTEXTPARAM.CREATOR, 1.0f, 0.0f, false);
        simulator.getParamBindingMgr().addParamBinding(binding);
        binding = new nvParamBinding(VIZPARAM.BIODIVERSITY_L2);
        binding.addTerm(CONTEXTPARAM.READ_FREQ, 1.0f, 0.0f, false);
        simulator.getParamBindingMgr().addParamBinding(binding);
        binding = new nvParamBinding(VIZPARAM.BIODIVERSITY_L3);
        binding.addTerm(CONTEXTPARAM.RATING, 1.0f, 0.0f, false);
        simulator.getParamBindingMgr().addParamBinding(binding);
        binding = new nvParamBinding(VIZPARAM.METABOLISM);
        binding.addTerm(CONTEXTPARAM.ADDRESSE, 1.0f, 0.0f, false);
        simulator.getParamBindingMgr().addParamBinding(binding);
        binding = new nvParamBinding(VIZPARAM.APPERANCE_COLOR_R);
        binding.addTerm(CONTEXTPARAM.ALERT, 1.0f, 0.0f, false);
        simulator.getParamBindingMgr().addParamBinding(binding);
        binding = new nvParamBinding(VIZPARAM.APPERANCE_COLOR_G);
        binding.addTerm(CONTEXTPARAM.CATEGORIES_SELECTED, 1.0f, 0.0f, false);
        simulator.getParamBindingMgr().addParamBinding(binding);
        binding = new nvParamBinding(VIZPARAM.APPERANCE_COLOR_B);
        binding.addTerm(CONTEXTPARAM.MIME_TYPE, 1.0f, 0.0f, false);
        simulator.getParamBindingMgr().addParamBinding(binding);
    }

    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
        if (height <= 0) { // avoid a divide by zero error!
            height = 1;
        }
        simulator.getRenderer().onReshape(x, y, width, height);
    }

    public void display(GLAutoDrawable drawable) {

        long diff = System.currentTimeMillis() - updatestamp;
        updatestamp += diff;
        float deltaT = (float) diff / 1000.0f;

        simulator.update(deltaT);
        simulator.render();
    }

    public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
    }
}

